package com.changgou.seckill.util;

import com.changgou.seckill.config.ConfirmMessageCallback;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author Jiang Yilin
 * @title: MessageSender
 * @projectName changgou_parent
 * @description: TODO
 * @date 2020/3/311:12
 */
@Component
public class MessageSender {

    private int retryTime = 3;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    ConfirmMessageCallback confirmMessageCallback;

    public static final String MESSAGE_CONFIRM_KEY="message_confirm_";

    public void sendMessage(String exchange,String routingKey,String message,String messageId) {
        sendMessage(exchange,routingKey,message,messageId,false);
    }

        //自定义消息发送方法
    public void sendMessage(String exchange,String routingKey,String message,String messageId,boolean isFirst){

       String id = "";
       if(isFirst){
           id = UUID.randomUUID().toString();
       }else{
           id = messageId;
       }
        //设置消息的唯一标识并存入到redis中
        CorrelationData correlationData = new CorrelationData(id);

        String key = MESSAGE_CONFIRM_KEY+correlationData.getId();
        if(isFirst){
            // 在redis里设置重试次数
            redisTemplate.opsForValue().set(key+"_retry",retryTime);
        }else{
            // 取出重试次数 进行减一的操作 <=0就不再发送
            Long decrement = redisTemplate.opsForValue().decrement(MESSAGE_CONFIRM_KEY+id + "_retry");
            if(decrement<=0){
                redisTemplate.delete(MESSAGE_CONFIRM_KEY+correlationData.getId());
                redisTemplate.delete(MESSAGE_CONFIRM_KEY+id + "_retry");
                return ;
            }
        }
        //将本次发送消息的相关元数据保存到redis中
        Map<String,String> map = new HashMap<>();
        map.put("exchange",exchange);
        map.put("routingKey",routingKey);
        map.put("message",message);
        map.put("messageId",correlationData.getId());

        redisTemplate.opsForHash().putAll(key,map);

        //携带着本次消息的唯一标识,进行数据发送
        rabbitTemplate.setConfirmCallback(confirmMessageCallback);
        rabbitTemplate.convertAndSend(exchange,routingKey,message,correlationData);

    }
}
